#include "Player.h"
#include "Object3D.h"
#include "Rectangle.h"
#include <stdlib.h>
//#include <windows.h>
#include <sstream>
#include <GL/glut.h>


using namespace std;

// Constructor 
Player::Player(){
	Object3D::Object3D("");
	MAX_SPEED = 1.5f;
	iDirection = 0;
	iLives = 3;
	bHasShoot = false;
	pmodel1 = NULL;

	// Physics variables
	fSpeed = 0.0f;
	fFriction = 41.0f;

	vTranslation->v[1] = -22.0f;
	// ship1
	vRotation->v[0] = 90.0f;
	vRotation->v[1] = 180.0f;
	//ship2
	//vRotation->v[0] = 90.0f;
	//vRotation->v[1] = 90.0f;
	vScale->v[0] = 1.5f;
	vScale->v[1] = 1.5f;
	rBoundingBox = new Rectangle(0.0f,0.0f,1.0f,1.0f);
}
Player::Player(string strTexturePath){
	Object3D::Object3D(strTexturePath);
	MAX_SPEED = 1.5f;
	iDirection = 0;
	iLives = 3;
	bHasShoot = false;
	pmodel1 = NULL;

	// Physics variables
	fSpeed = 0.0f;
	fFriction = 41.0f;

	vTranslation->v[1] = -22.0f;
	vRotation->v[0] = 90.0f;
	rBoundingBox = new Rectangle(0.0f,0.0f,1.0f,1.0f);

}

// Main Functions
void Player::Update(float deltaTime){
	if (iDirection != 0){
		Player::Move(deltaTime);
	}
	rBoundingBox->SetX(vTranslation->v[0]);
	rBoundingBox->SetY(vTranslation->v[1]);
}
void Player::Draw(){
	if (iLives>0){
		glTranslatef(vTranslation->v[0],vTranslation->v[1],0.0f);	
		glScalef(vScale->v[0], vScale->v[1], vScale->v[2]); //Scale 
		glRotatef(vRotation->v[0], 1.0f, 0.0f, 0.0f); //Rotate about the x-axis
		glRotatef(vRotation->v[1], 0.0f, 1.0f, 0.0f); //Rotate about the y-axis
		glRotatef(vRotation->v[2], 0.0f, 0.0f, 1.0f); //Rotate about the z-axis
		// Load the model only if it hasn't been loaded before
		// If it's been loaded then pmodel1 should be a pointer to the model geometry data...otherwise it's null
		if (!pmodel1) 
		{
			// this is the call that actualy reads the OBJ and creates the model object
			pmodel1 = glmReadOBJ("Ship1.obj");	
			if (!pmodel1) exit(0);
			// This will rescale the object to fit into the unity matrix
			// Depending on your project you might want to keep the original size and positions you had in 3DS Max or GMAX so you may have to comment this.
			glmUnitize(pmodel1);
			// These 2 functions calculate triangle and vertex normals from the geometry data.
			// To be honest I had some problem with very complex models that didn't look to good because of how vertex normals were calculated
			// So if you can export these directly from you modeling tool do it and comment these line
			// 3DS Max can calculate these for you and GLM is perfectly capable of loading them
			glmFacetNormals(pmodel1);        
			glmVertexNormals(pmodel1, 90.0);
		}
		// This is the call that will actualy draw the model
		// Don't forget to tell it if you want textures or not :))
		glmDraw(pmodel1, GLM_SMOOTH| GLM_TEXTURE);

		//glBegin(GL_TRIANGLES);
		//
		////Triangle
		//glVertex3f(0.5f, -0.5f, 0.0f);
		//glVertex3f(0.0f, 0.5f, 0.0f);
		//glVertex3f(-0.5f, -0.5f, 0.0f);
		//
		//glEnd();
		glPopMatrix(); //Undo the move
		glPushMatrix(); //Save the current state 
	}
}

void Player::Move(float deltaTime){
	fSpeed -=  deltaTime/1000*fFriction;
	stringstream ss;
	ss << fSpeed;

	cout<< ss.str() <<endl;
	if (fSpeed <=0) // Speed cant affect the object's movement
		fSpeed = 0;
	else{
		if (iDirection<0){
			vTranslation->v[0] -= fSpeed; // Move object west along the x-axis
			if (vTranslation->v[0]<=-1*fMaxWidth)
				vTranslation->v[0] = -1*fMaxWidth;
		}
		else
			vTranslation->v[0] += fSpeed; // Move object east along the x-axis
			if (vTranslation->v[0]>= fMaxWidth)
				vTranslation->v[0] = fMaxWidth;
	}
}
Bullet Player::Shoot(){
	Bullet* theBullet = new Bullet();
	if (!bHasShoot){
		theBullet->Initialize(new Vec3f(vTranslation->v[0],vTranslation->v[1]+2.0f,0.0f));
		theBullet->SetDirection(1);
		bHasShoot = true;
	}
	else{
		theBullet->Initialize(new Vec3f(vTranslation->v[0],100.0f,0.0f));
		theBullet->SetDirection(-1);
	}
	return *theBullet;
}

void Player::Reset(){
	vTranslation->v[0] = 0.0f;
	DecreaseLives();
}

void Player::IncreaseLives(){
	iLives++;
}

void Player::DecreaseLives(){
	iLives--;
}

// Setters and Getters
void Player::SetDirection(int iDirection){
	this->iDirection = iDirection;
	if (iDirection != 0)
		fSpeed = MAX_SPEED;
	
}
void Player::SetHasShoot(bool bHasShoot){
	this->bHasShoot = bHasShoot;
}
int Player::GetDirection(){
	return iDirection;
}
int Player::GetLives(){
	return iLives;
}

